//
//  ZLDownloaderImageView.swift
//  ZLKit_Swift
//
//  Created by iOS on 2022/8/5.
//

import Foundation
import SnapKit

// 我暂时没有找到swift podspec 中如何添加 Objectivc-C 桥接文件的方式，尝试了很多，但是没有成功，暂时先把设置图片的任务交给外界。
//import SDWebImage

open class ZLDownloaderImageView: UIImageView {
    
    public var indexPath: IndexPath? = nil
    
    /// 第一个参数，是路径
    /// 第二个参数，是传递给内部的，用来响应returnImageSize函数
    public var loadImageObserver: Params_two_void<String, Params_one_void<UIImage?>> = nil
    
    /// 优先尝试缩略图地址拼接
    /// 链接后面拼接参数，以控制图片的大小
    /// COS（腾讯云）拼参文档：https://cloud.tencent.com/document/product/436/44880         示例："?imageMogr2/thumbnail/2097152@"
    /// OSS（阿里云）拼参文档：https://help.aliyun.com/document_detail/44688.html              示例："?x-oss-process=image/resize,w_\(width_int),m_lfit"
    public var priorityTryThumbnailUrlAppend: Basic_return<String> = nil
    
    weak private var _downloader: AccreteDownloader? = nil
    weak public var downloader: AccreteDownloader? {
        set {
                
            // 先清理控件上的图像信息
            image = nil
            
            // 先关闭之前注册的监听事件
            newValue?.progressSync = nil
            newValue?.setImage = nil
            newValue?.loadingStateSync = nil
            newValue?.priorityTryThumbnailUrlAppend = nil

            loadingView.state = newValue?.loadingState ?? .loading
            
            // 再注册新的监听事件
            newValue?.progressSync = {[weak self] progress in
                self?.loadingView.boxView.progress = Float(progress)
            }
            newValue?.setImage = {[weak self] path, url, returnImageSize in
                guard let self = self, url == (self.downloader?.url ?? "") else { return }
                
                // 暂时先把加载图片的任务交给外界，等我找到了桥接OC文件的方式，再调整该段内容
                self.loadImageObserver?(path, { image in
                    if let image = image {
                        returnImageSize?(image.size)
                    }
                })
                
            }
            newValue?.loadingStateSync = {[weak self] state in
                guard let self = self else { return }
                self.loadingView.state = state
            }
            newValue?.priorityTryThumbnailUrlAppend = {[weak self] in
                self?.priorityTryThumbnailUrlAppend?() ?? ""
            }
            
            // 开始加载数据
            startLoadData(newValue: newValue)
            
            loadingView.boxView.progress = Float(newValue?.progress ?? 0)
            _downloader = newValue
        }
        get {
            return _downloader
        }
    }
    
    open override var image: UIImage? {
        didSet {
            didSetImage?(image)
        }
    }
    
    /// 已经设置了图片的事件
    public var didSetImage: Params_one_void<UIImage?> = nil
    
    lazy var loadingView: LoadingView = {
        let view = LoadingView(loadingSize: loadingSize, progressWidth: progressWidth, progressColor: progressColor)
        view.isHidden = true
        return view
    }()
    
    private let loadingSize: CGFloat
    private let progressWidth: CGFloat
    private let progressColor: UIColor
    public init(loadingSize: CGFloat = 35, progressWidth: CGFloat = 4, progressColor: UIColor = .red) {
        self.loadingSize = loadingSize
        self.progressWidth = progressWidth
        self.progressColor = progressColor
        super.init(frame: .zero)
        isUserInteractionEnabled = true
        addSubview(loadingView)
        loadingView.snp.makeConstraints({
            $0.edges.equalToSuperview()
        })
        loadingView.tryAction = {[weak self] in
            guard let self = self else { return }
            self.startLoadData(newValue: self.downloader)
        }
    }
    
    required public init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    /// 分情况加载数据
    func startLoadData(newValue: AccreteDownloader?) {
        let url = newValue?.url ?? ""
        let isExistOriginData = AccreteDownloader.isExistOriginData(url: url, didTryRemoveParams: newValue?.didTryRemoveParams ?? false, lowAccuracy: newValue?.lowAccuracy ?? false, thumbnailUrlParams: (newValue?.priorityTryThumbnailUrlAppend?() ?? ""))
        if isExistOriginData {
            newValue?.startRequest(remote: false)
        }else {
            // 判断能不能进入白名单 -- 相同的图片地址会被阻挡在外
            if !ZLDownloaderUrlWhiteList.shared.whiteList.contains(url) {
                ZLDownloaderUrlWhiteList.shared.whiteList.append(url)
                newValue?.startRequest(remote: true)
                newValue?.isOnRequest = true
            }
        }
    }
    
}
